package git.soulbgm.utils;

import io.netty.buffer.Unpooled;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelFutureListener;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 通道工具类
 *
 * @author SoulBGM
 * @date 2021-03-29
 */
public class ChannelUtil {

    private static Map<String, ChannelFutureListener> channelFutureListenerMap = new ConcurrentHashMap<>();

    private static Map<String, ChannelFuture> channelFutureMap = new ConcurrentHashMap<>();

    public static void putChannelFutureListener(String ip, int port, ChannelFutureListener channelFutureListener) {
        if (ip != null && port != 0 && channelFutureListener != null) {
            channelFutureListenerMap.put(ip + ":" + port, channelFutureListener);
        }
    }

    public static ChannelFutureListener getChannelFutureListener(String ip, int port) {
        if (ip != null && port != 0) {
            return channelFutureListenerMap.get(ip + ":" + port);
        }
        return null;
    }

    public static void putChannelFuture(String ip, int port, ChannelFuture channelFuture) {
        if (ip != null && port != 0 && channelFuture != null) {
            channelFutureMap.put(ip + ":" + port, channelFuture);
        }
    }

    public static ChannelFuture getChannelFuture(String ip, int port) {
        if (ip != null && port != 0) {
            return channelFutureMap.get(ip + ":" + port);
        }
        return null;
    }

    public static void removeChannelFuture(String ip, int port) {
        if (ip != null && port != 0) {
            channelFutureMap.remove(ip + ":" + port);
        }
    }

    /**
     * TCP防止粘包的分隔符
     */
    public static final byte[] TCP_DELIMITER_BYTE = {120, 120, 120, 120, -120, -120, -120, -120};

    /**
     * 发送数据
     *
     * @param channel 通道
     * @param data    数据
     * @return 通道异步任务结果
     */
    public static ChannelFuture tcpSendMsg(Channel channel, byte[] data) {
        if (channel == null) {
            return null;
        }
        data = byteMergerAll(data, TCP_DELIMITER_BYTE);
        return channel.writeAndFlush(Unpooled.copiedBuffer(data));
    }

    /**
     * 发送数据并关闭通道
     *
     * @param channel 通道
     * @param data    数据
     * @return true成功，false失败
     */
    public boolean tcpSendMsgAndClose(Channel channel, byte[] data) {
        final boolean[] result = {false};
        ChannelFuture future = tcpSendMsg(channel, data);
        if (future != null) {
            future.addListener(new ChannelFutureListener() {
                @Override
                public void operationComplete(ChannelFuture future) {
                    future.channel().close();
                    result[0] = true;
                }
            });
        }
        return result[0];
    }

    /**
     * 将多个byte[]组合成一个byte[]
     *
     * @param values
     * @return
     */
    public static byte[] byteMergerAll(byte[]... values) {
        int lengthByte = 0;
        for (int i = 0; i < values.length; i++) {
            lengthByte += values[i].length;
        }
        byte[] allByte = new byte[lengthByte];

        int countLength = 0;
        for (int i = 0; i < values.length; i++) {
            byte[] b = values[i];
            System.arraycopy(b, 0, allByte, countLength, b.length);
            countLength += b.length;
        }
        return allByte;
    }

    public static byte[] hexStrToBytes(String hex) {
        String[] split = hex.split("\\s+");
        byte[] result = new byte[split.length];
        for (int i = 0; i < split.length; i++) {
            String s = split[i];
            if ("".equals(s)) {
                continue;
            }
            result[i] = (byte) Integer.parseInt(s, 16);
        }
        return result;
    }

    public static String bytesString16(byte[] b) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < b.length; i++) {
            sb.append(String.format("%02x", b[i]));
            sb.append(" ");
        }
        return sb.toString();
    }

}
